from flask import Flask, render_template, request, jsonify, send_from_directory
import logging
import os
import requests
from database import get_db_connection, init_db
from config_generator import generate_frpc_config

app = Flask(__name__)

# 配置日志
logging.basicConfig(level=logging.ERROR)
logger = logging.getLogger(__name__)

# FRP API配置
FRP_API_URL = "http://39.104.71.213:7500/api/proxy/tcp"
FRP_API_HEADERS = {
    'authorization': 'Basic YWRtaW46YWRtaW4=',
    'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
    'Accept': '*/*',
    'Host': '39.104.71.213:7500',
    'Connection': 'keep-alive'
}

def get_file_size(size_in_bytes):
    """将字节大小转换为人类可读的格式"""
    for unit in ['字节', 'KB', 'MB', 'GB']:
        if size_in_bytes < 1024.0:
            return f"{size_in_bytes:.1f} {unit}"
        size_in_bytes /= 1024.0
    return f"{size_in_bytes:.1f} TB"

@app.route('/')
def index():
    data_cube_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Data Cube')
    files = []
    
    if os.path.exists(data_cube_dir):
        for filename in os.listdir(data_cube_dir):
            file_path = os.path.join(data_cube_dir, filename)
            if os.path.isfile(file_path):
                size = get_file_size(os.path.getsize(file_path))
                files.append({
                    'name': filename,
                    'size': size
                })
    
    # 获取服务器和客户端配置
    conn = get_db_connection()
    server_configs = conn.execute('SELECT * FROM frp_server_config').fetchall()
    client_configs = conn.execute('SELECT * FROM frp_client_config').fetchall()
    conn.close()
    
    return render_template('index.html', 
                         files=files,
                         server_configs=server_configs,
                         client_configs=client_configs)

@app.route('/download/<filename>')
def download_file(filename):
    data_cube_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Data Cube')
    return send_from_directory(data_cube_dir, filename, as_attachment=True)

@app.route('/add_server_config', methods=['POST'])
def add_server_config():
    try:
        data = request.json
        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute('''
            INSERT INTO frp_server_config (server_name, server_addr, server_port, token)
            VALUES (?, ?, ?, ?)
        ''', (data['server_name'], data['server_addr'], data['server_port'], data['token']))
        conn.commit()
        new_id = cursor.lastrowid
        conn.close()
        return jsonify({'success': True, 'id': new_id})
    except Exception as e:
        logger.error(f"添加服务端配置失败: {str(e)}")
        return jsonify({'success': False, 'error': str(e)})

@app.route('/get_server_config/<id>')
def get_server_config(id):
    try:
        conn = get_db_connection()
        config = conn.execute('SELECT * FROM frp_server_config WHERE id = ?', (id,)).fetchone()
        conn.close()
        if config:
            return jsonify({
                'server_name': config['server_name'],
                'server_addr': config['server_addr'],
                'server_port': config['server_port'],
                'token': config['token']
            })
        return jsonify({'error': 'Config not found'}), 404
    except Exception as e:
        logger.error(f"获取服务端配置失败: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/update_server_config/<id>', methods=['POST'])
def update_server_config(id):
    try:
        data = request.json
        conn = get_db_connection()
        conn.execute('''
            UPDATE frp_server_config
            SET server_name = ?, server_addr = ?, server_port = ?, token = ?
            WHERE id = ?
        ''', (data['server_name'], data['server_addr'], data['server_port'], data['token'], id))
        conn.commit()
        conn.close()
        return jsonify({'success': True})
    except Exception as e:
        logger.error(f"更新服务端配置失败: {str(e)}")
        return jsonify({'success': False, 'error': str(e)})

@app.route('/delete_server_config/<int:id>', methods=['POST'])
def delete_server_config(id):
    try:
        conn = get_db_connection()
        conn.execute('DELETE FROM frp_server_config WHERE id = ?', (id,))
        conn.commit()
        conn.close()
        return jsonify({'code': 0, 'msg': '删除成功'})
    except Exception as e:
        logger.error(f"删除服务器配置失败: {str(e)}")
        return jsonify({'code': 1, 'msg': str(e)})

@app.route('/add_client_config', methods=['POST'])
def add_client_config():
    try:
        data = request.json
        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute('''
            INSERT INTO frp_client_config (name, type, local_ip, local_port, remote_port)
            VALUES (?, ?, ?, ?, ?)
        ''', (data['name'], data['type'], data['local_ip'], data['local_port'], data['remote_port']))
        conn.commit()
        new_id = cursor.lastrowid
        conn.close()
        return jsonify({'success': True, 'id': new_id})
    except Exception as e:
        logger.error(f"添加客户端配置失败: {str(e)}")
        return jsonify({'success': False, 'error': str(e)})

@app.route('/get_client_config/<id>')
def get_client_config(id):
    try:
        conn = get_db_connection()
        config = conn.execute('SELECT * FROM frp_client_config WHERE id = ?', (id,)).fetchone()
        conn.close()
        if config:
            return jsonify({
                'name': config['name'],
                'type': config['type'],
                'local_ip': config['local_ip'],
                'local_port': config['local_port'],
                'remote_port': config['remote_port']
            })
        return jsonify({'error': 'Config not found'}), 404
    except Exception as e:
        logger.error(f"获取客户端配置失败: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/update_client_config/<id>', methods=['POST'])
def update_client_config(id):
    try:
        data = request.json
        conn = get_db_connection()
        conn.execute('''
            UPDATE frp_client_config
            SET name = ?, type = ?, local_ip = ?, local_port = ?, remote_port = ?
            WHERE id = ?
        ''', (data['name'], data['type'], data['local_ip'], data['local_port'], data['remote_port'], id))
        conn.commit()
        conn.close()
        return jsonify({'success': True})
    except Exception as e:
        logger.error(f"更新客户端配置失败: {str(e)}")
        return jsonify({'success': False, 'error': str(e)})

@app.route('/delete_client_config/<int:id>', methods=['POST'])
def delete_client_config(id):
    try:
        conn = get_db_connection()
        conn.execute('DELETE FROM frp_client_config WHERE id = ?', (id,))
        conn.commit()
        conn.close()
        return jsonify({'code': 0, 'msg': '删除成功'})
    except Exception as e:
        logger.error(f"删除客户端配置失败: {str(e)}")
        return jsonify({'code': 1, 'msg': str(e)})

@app.route('/generate_config', methods=['POST'])
def generate_config():
    try:
        data = request.json
        conn = get_db_connection()
        
        # 获取服务器配置
        server_config = conn.execute('SELECT * FROM frp_server_config WHERE id = ?', (data['server_id'],)).fetchone()
        if not server_config:
            return jsonify({'error': 'Server config not found'}), 404
        
        # 获取选中的客户端配置
        client_configs = []
        for client_id in data['client_ids']:
            client_config = conn.execute('SELECT * FROM frp_client_config WHERE id = ?', (client_id,)).fetchone()
            if client_config:
                client_configs.append(dict(client_config))
        
        conn.close()
        
        # 生成配置文件内容
        config_content = generate_frpc_config(dict(server_config), client_configs)
        return jsonify({'code': 0, 'msg': 'success', 'data': config_content})
    except Exception as e:
        logger.error(f"生成配置文件失败: {str(e)}")
        return jsonify({'code': 1, 'msg': str(e)})

@app.route('/generate_selected_config', methods=['POST'])
def generate_selected_config():
    try:
        data = request.get_json()
        server_id = data.get('server_id')
        client_ids = data.get('client_ids', [])

        if not server_id or not client_ids:
            return jsonify({'code': 1, 'msg': '请选择服务器和客户端配置'})

        conn = get_db_connection()
        server_config = conn.execute('SELECT * FROM frp_server_config WHERE id = ?', (server_id,)).fetchone()
        client_configs = []
        for client_id in client_ids:
            client = conn.execute('SELECT * FROM frp_client_config WHERE id = ?', (client_id,)).fetchone()
            if client:
                client_configs.append(dict(client))
        conn.close()

        if not server_config:
            return jsonify({'code': 1, 'msg': '服务器配置不存在'})
        if not client_configs:
            return jsonify({'code': 1, 'msg': '客户端配置不存在'})

        # 生成服务器配置
        config = f"""serverAddr = "{server_config['server_addr']}"
serverPort = {server_config['server_port']}
auth.token = "{server_config['token']}"
"""

        # 生成客户端配置
        if client_configs:
            proxy_configs = []
            for client in client_configs:
                proxy_config = f"""[[proxies]]
name = "{client['name']}"
type = "{client['type']}"
localIP = "{client['local_ip']}"
localPort = {client['local_port']}
remotePort = {client['remote_port']}"""
                proxy_configs.append(proxy_config)
            
            config += "\n" + "\n\n".join(proxy_configs)

        # 保存配置到文件
        config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Data Cube', 'frpc.toml')
        os.makedirs(os.path.dirname(config_path), exist_ok=True)
        with open(config_path, 'w', encoding='utf-8') as f:
            f.write(config)

        return jsonify({
            'code': 0,
            'msg': '配置生成成功',
            'config': config,
            'command': 'frpc.exe -c frpc.toml'
        })

    except Exception as e:
        logger.error(f"生成配置失败: {str(e)}")
        return jsonify({'code': 1, 'msg': str(e)})

@app.route('/api/proxy/status')
def proxy_status():
    try:
        response = requests.get(FRP_API_URL, headers=FRP_API_HEADERS)
        if response.status_code == 200:
            data = response.json()
            return jsonify({'code': 0, 'proxies': data})
        else:
            return jsonify({'code': 1, 'msg': f'API请求失败: {response.status_code}'})
    except Exception as e:
        logger.error(f"获取代理状态失败: {str(e)}")
        return jsonify({'code': 1, 'msg': str(e)})
